﻿using sipfe.model.dataAccess;
using sipfe.model.vo;
using sipfe.util;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity.Validation;
using System.Linq;
using System.Text;

namespace sipfe.model.bandeja
{
   public class BandejaDAO
    {
       private BDSIPFEEntities db = new BDSIPFEEntities();

       public int marcarRecepFisicaAhoraDAO(decimal nIdeSol, decimal nSeqPaso, decimal nSeqactor, string idUsuario)
       {
           SIPDetSoliActor sipDetSoliActor = new SIPDetSoliActor();
           sipDetSoliActor = db.SIPDetSoliActor.Where(s => s.nIdeSol == nIdeSol && s.nSeqPaso == nSeqPaso && s.nSeqActor == nSeqactor).FirstOrDefault();
           sipDetSoliActor.dtFecRecFisica = DateTime.Now;
           sipDetSoliActor.nIdUsuRecepFis = Int32.Parse(idUsuario);
           db.Entry(sipDetSoliActor).State = EntityState.Modified;
           db.SaveChanges();
           return (sipDetSoliActor.dtFecRecFisica != null) ? 1 : 0;
       }

       public int recepcionFisicaLoteFinDAO(DateTime fecha, string cadena, string idUsuario)
       {
           SIPDetSoliActor sipDetSoliActor = null;
           int nIdeSol      =   0;
           int nSeqPaso     =   0;
           int nSeqActor    =   0;

           String[] arrayActor = cadena.Split(',');
           foreach (String pkActor in arrayActor)
           {
               String[] arrayPk = pkActor.Split('|');
               nIdeSol      =   Int32.Parse(arrayPk[0]);
               nSeqPaso     =   Int32.Parse(arrayPk[1]);
               nSeqActor    =   Int32.Parse(arrayPk[2]);
               sipDetSoliActor = new SIPDetSoliActor();
               sipDetSoliActor = db.SIPDetSoliActor.Where(s => s.nIdeSol == nIdeSol && s.nSeqPaso == nSeqPaso && s.nSeqActor == nSeqActor).FirstOrDefault();
               sipDetSoliActor.dtFecRecFisica = fecha;
               sipDetSoliActor.nIdUsuRecepFis = Int32.Parse(idUsuario);
               db.Entry(sipDetSoliActor).State = EntityState.Modified;
               db.SaveChanges();
           }
           return 1;
       }


       public String[] registraDerivacionDAO(SIPDetSolicitud sipDetSolicitud)
       {           
           decimal n_IdeSol         =   sipDetSolicitud.nIdeSol;
           decimal n_SeqPaso        =   sipDetSolicitud.nSeqPaso;
           decimal n_SeqActor       =   sipDetSolicitud.nSeqActor;
           decimal nextPaso         =   getNextSeqPaso(n_IdeSol);
           sipDetSolicitud.nSeqPaso =   nextPaso;
           sipDetSolicitud.dtFecReg =   DateTime.Now;

           //registramos los actores           
           sipDetSolicitud.SIPDetSoliActor.Add(getActorDerivador(sipDetSolicitud, Int32.Parse(Constante.TIPO_BANDEJA.BANDEJA_SALIDA)));

           string destinatarios = sipDetSolicitud.vDestino;
           int seqActor = 1;

           string[] arrayDestinos = destinatarios.Split(',');
           foreach (string destino in arrayDestinos)
           {
               seqActor++;
               sipDetSolicitud.SIPDetSoliActor.Add(getActorDestinatario(sipDetSolicitud, seqActor, Decimal.Parse(destino)));
           }

           //sipDetSolicitud.SIPDetArchivo.Add(sipDetArchivo);

           if (sipDetSolicitud.SIPDetArchivo.ElementAt(0) != null)
           {
               sipDetSolicitud.SIPDetArchivo.ElementAt(0).nIdeSol = n_IdeSol;
               sipDetSolicitud.SIPDetArchivo.ElementAt(0).nSeqPaso = nextPaso;
           }

           db.SIPDetSolicitud.Add(sipDetSolicitud);
           db.SaveChanges();

           //actualizamos la fecha de derivacion del registro anterior y el tipo de bandeja de salida
           SIPDetSoliActor sipDetSoliActorOld = new SIPDetSoliActor();
           sipDetSoliActorOld = db.SIPDetSoliActor.Where(x => x.nIdeSol == n_IdeSol && x.nSeqPaso == n_SeqPaso && x.nSeqActor == n_SeqActor).FirstOrDefault();
           sipDetSoliActorOld.dtFecDerivacion = DateTime.Now;
           //sipDetSoliActorOld.nIdeTipoBandeja = Int32.Parse(Constante.TIPO_BANDEJA.BANDEJA_SALIDA);
           db.Entry(sipDetSoliActorOld).State = EntityState.Modified;
           db.SaveChanges();

           //return (sipDetSolicitud.nSeqPaso > 0) ? "1" : "error";

           return new String[] { n_IdeSol.ToString(), nextPaso.ToString()};
       }

       private decimal getNextSeqPaso(decimal n_IdeSol)
       {
           StringBuilder sql = new StringBuilder();
           sql.Append("select isnull(MAX(nSeqpaso),0) + 1 from SIPDetSolicitud where nIdeSol=").Append(n_IdeSol);
           var max = db.Database.SqlQuery<Decimal>(sql.ToString());
           List<Decimal> valores = max.ToList<Decimal>();
           Decimal seqPaso = valores.First<Decimal>();
           return seqPaso;
       }

       public SIPDetSoliActor getActorDerivador(SIPDetSolicitud sipDetSolicitud,decimal n_tipoBandeja) {
           
           SIPDetSoliActor sipDetSoliActor = new SIPDetSoliActor();
           sipDetSoliActor.nIdeSol              =   sipDetSolicitud.nIdeSol;
           sipDetSoliActor.nSeqPaso             =   sipDetSolicitud.nSeqPaso;
           sipDetSoliActor.nSeqActor            =   1;
           sipDetSoliActor.nIdeTipoBandeja      =   n_tipoBandeja;
           sipDetSoliActor.nIdeTipoActor        =   1;
           sipDetSoliActor.nIdeTipoCategoria    =   1;
           sipDetSoliActor.nIdeDep              =   sipDetSolicitud.nIdeDep;
           sipDetSoliActor.nIdeFuncionario      =   sipDetSolicitud.nIdeFuncionario;
           sipDetSoliActor.dtFecRecepcion       =   DateTime.Now;
           sipDetSoliActor.dtFecDerivacion      =   DateTime.Now;
           sipDetSoliActor.dtFecRecFisica       =   DateTime.Now;
           sipDetSoliActor.dtFecLectura         =   DateTime.Now;
           sipDetSoliActor.nIdUsuLectura        =   sipDetSolicitud.nIdeUsuReg;
           sipDetSoliActor.nIdUsuRecepFis       =   sipDetSolicitud.nIdeUsuReg;

           return sipDetSoliActor;
       }

       public SIPDetSoliActor getActorDestinatario(SIPDetSolicitud sipDetSolicitud, decimal seqActor, decimal nIdeDestino)
       {             
           SIPDetSoliActor sipDetSoliActor = new SIPDetSoliActor();
           sipDetSoliActor.nIdeSol              =   sipDetSolicitud.nIdeSol;
           sipDetSoliActor.nSeqPaso             =   sipDetSolicitud.nSeqPaso;
           sipDetSoliActor.nSeqActor            =   seqActor;
           sipDetSoliActor.nIdeTipoBandeja      =   1;
           sipDetSoliActor.nIdeTipoActor        =   2;
           sipDetSoliActor.nIdeTipoCategoria    =   2;
           sipDetSoliActor.nIdeDep              =   nIdeDestino;
           sipDetSoliActor.nIdeFuncionario      =   sipDetSolicitud.nIdeFuncionario;
           sipDetSoliActor.dtFecRecepcion       =   DateTime.Now;
           return sipDetSoliActor;
       }

       private decimal getNextSeqActor(decimal n_IdeSol, decimal n_SeqPaso)
       {
           StringBuilder sql = new StringBuilder();
           sql.Append("select isnull(MAX(nSeqpaso),0) + 1 from SIPDetSoliActor where nIdeSol=").Append(n_IdeSol);
           sql.Append(" and nSeqPaso=").Append(n_SeqPaso);

           var max = db.Database.SqlQuery<Decimal>(sql.ToString());
           List<Decimal> valores = max.ToList<Decimal>();
           Decimal seqPasoActor = valores.First<Decimal>();
           return seqPasoActor;
       }

       public void insertaArchivosDAO(byte[] bytesFile, int n_IdeSol, int nextPaso, string nameFile)
       {
           SIPDetArchivo sipDetArchivo = new SIPDetArchivo();
           sipDetArchivo.nIdeTipoAdj    =   1;
           sipDetArchivo.vContenType    =   "zzzzz";
           sipDetArchivo.vNomAdj        =   nameFile;
           sipDetArchivo.vComentario    =   "comentarito";
           sipDetArchivo.imArchivoAdj   =   bytesFile;
           sipDetArchivo.nIdeSol        =   n_IdeSol;
           sipDetArchivo.nSeqPaso       =   nextPaso;
           sipDetArchivo.nIdeUsuReg     =   2;
           db.SIPDetArchivo.Add(sipDetArchivo);
           db.SaveChanges();
       }

       public List<SIPDetArchivo> listaArchivosAdjuntosDAO(int n_IdeSol)
       {
           return db.SIPDetArchivo.Where(x => x.nIdeSol == n_IdeSol).ToList();
       }

       public String[] registraBitacoraDAO(SIPDetBitacora sipDetBitacora)
       {

           try
            {
                sipDetBitacora.dtFecReg =   DateTime.Now;
                sipDetBitacora.vSumilla =   sipDetBitacora.vSumillaBita;

                if (sipDetBitacora.SIPDetArchivo.ElementAt(0) != null)
                {
                    sipDetBitacora.SIPDetArchivo.ElementAt(0).nIdeSol = sipDetBitacora.nIdeSol;
                    sipDetBitacora.SIPDetArchivo.ElementAt(0).nSeqPaso = sipDetBitacora.nSeqPaso;
                }
                
                ///  sipDetSolicitud.SIPDetArchivo.ElementAt(0).nIdeSol = n_IdeSol;
               // sipDetSolicitud.SIPDetArchivo.ElementAt(0).nSeqPaso = nextPaso;
               
                db.SIPDetBitacora.Add(sipDetBitacora);
                db.SaveChanges();
            }
           catch (DbEntityValidationException dbEx)
           {
               var errorMessages = dbEx.EntityValidationErrors.SelectMany(x => x.ValidationErrors).Select(x => x.ErrorMessage);
               var fullErrorMessage = string.Join("; ", errorMessages);
               var exceptionMessage = string.Concat(dbEx.Message, " The validation errors are: ", fullErrorMessage);
               throw new DbEntityValidationException(exceptionMessage, dbEx.EntityValidationErrors);
           }
           
           return new String[] { "1" };
       }

       public List<SIPDetBitacora> listaBitacoraDAO(int n_IdeSol)
       {
           //return db.SIPDetBitacora.Where(x => x.nIdeSol == n_IdeSol).ToList();
           return db.SIPDetBitacora.Where(x => x.nIdeSol == n_IdeSol).OrderBy(x => x.dtFecReg).ToList();
       }



       public List<OptionsVO> getListaPersonasPorAreaDAO(int nIdeDepUser)
       {
           var resultado = (from detFuncDep in db.SIPDetFuncionarioDepen
                            join maeFuncionario in db.SIPMaeFuncionario
                            on detFuncDep.nIdeFuncionario equals maeFuncionario.nIdeFuncionario
                            where (detFuncDep.nIdeDep == nIdeDepUser && (detFuncDep.dFecFinVig == null ? DateTime.Now : detFuncDep.dFecFinVig) >= DateTime.Now && detFuncDep.dFecIniVig <= DateTime.Now)
                                select new OptionsVO()
                                {
                                    nIdeItemD = detFuncDep.nIdeFuncionario,
                                    vDescrItem = maeFuncionario.vPrimNombre + " " + maeFuncionario.vPrimApellido + " " + maeFuncionario.vSegApellido
                                }
                            );
           return resultado.ToList();
           
          // return db.SIPDetFuncionarioDepen.Where(x => x.nIdeDep == nIdeDepUser && (x.dFecFinVig == null ? DateTime.Now : x.dFecFinVig)  >= DateTime.Now && x.dFecIniVig <= DateTime.Now).ToList();
       }



       public string[] registraAsignacionDAO(SIPDetSolicitud sipDetSolicitud)
       {
           try
            {
                decimal n_IdeSol            =   sipDetSolicitud.nIdeSol;
                decimal n_SeqPaso           =   sipDetSolicitud.nSeqPaso;
                decimal n_SeqActor          =   sipDetSolicitud.nSeqActor;
                decimal nextPaso            =   getNextSeqPaso(n_IdeSol);
                sipDetSolicitud.nSeqPaso    =   nextPaso;
                sipDetSolicitud.dtFecReg    =   DateTime.Now;
                sipDetSolicitud.nIdePara    =   sipDetSolicitud.nIdeAccionAsig;
                sipDetSolicitud.nFolios     =   sipDetSolicitud.nFoliosAsig;
                sipDetSolicitud.vSumilla    =   sipDetSolicitud.vSumillaAsig;

                //registramos los actores           
                sipDetSolicitud.SIPDetSoliActor.Add(getActorDerivador(sipDetSolicitud,2));
               // el actor asignado
               sipDetSolicitud.SIPDetSoliActor.Add(getActorAsignado(sipDetSolicitud,2));

                db.SIPDetSolicitud.Add(sipDetSolicitud);
                db.SaveChanges();

                //actualizamos la fecha de derivacion del registro anterior
                SIPDetSoliActor sipDetSoliActorOld = new SIPDetSoliActor();
                sipDetSoliActorOld = db.SIPDetSoliActor.Where(x => x.nIdeSol == n_IdeSol && x.nSeqPaso == n_SeqPaso && x.nSeqActor == n_SeqActor).FirstOrDefault();
                sipDetSoliActorOld.dtFecDerivacion = DateTime.Now;
                db.Entry(sipDetSoliActorOld).State = EntityState.Modified;
                db.SaveChanges();





            }
           catch (DbEntityValidationException dbEx)
           {
               var errorMessages = dbEx.EntityValidationErrors.SelectMany(x => x.ValidationErrors).Select(x => x.ErrorMessage);
               var fullErrorMessage = string.Join("; ", errorMessages);
               var exceptionMessage = string.Concat(dbEx.Message, " The validation errors are: ", fullErrorMessage);
               throw new DbEntityValidationException(exceptionMessage, dbEx.EntityValidationErrors);
           }
           return new String[] { "1" };
       }

       public SIPDetSoliActor getActorAsignado(SIPDetSolicitud sipDetSolicitud, decimal n_tipoBandeja)
       {

           SIPDetSoliActor sipDetSoliActor = new SIPDetSoliActor();
           sipDetSoliActor.nIdeSol = sipDetSolicitud.nIdeSol;
           sipDetSoliActor.nSeqPaso = sipDetSolicitud.nSeqPaso;
           sipDetSoliActor.nSeqActor = 2;
           sipDetSoliActor.nIdeTipoBandeja = n_tipoBandeja;
           sipDetSoliActor.nIdeTipoActor = 2;
           sipDetSoliActor.nIdeTipoCategoria = 1;
           sipDetSoliActor.nIdeDep = sipDetSolicitud.nIdeDep;
           sipDetSoliActor.nIdeFuncionario = sipDetSolicitud.nFuncionarioAsigna;
           sipDetSoliActor.dtFecRecepcion = DateTime.Now;
           return sipDetSoliActor;
       }

       public void setFechaLecturaDAO(int n_IdeSol, int n_SeqPaso, int n_SeqActor, int id_Usuario)
       {
           SIPDetSoliActor sipDetSoliActor = new SIPDetSoliActor();
           sipDetSoliActor = db.SIPDetSoliActor.Where(s => s.nIdeSol == n_IdeSol && s.nSeqPaso == n_SeqPaso && s.nSeqActor == n_SeqActor).FirstOrDefault();
           sipDetSoliActor.dtFecLectura = DateTime.Now;
           sipDetSoliActor.nIdUsuLectura = id_Usuario;
           db.Entry(sipDetSoliActor).State = EntityState.Modified;
           db.SaveChanges();
       }
    }
}
